#pragma once

#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QMatrix4x4>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QKeyEvent>
#include <QPointF>
#include <QVector4D>
#include <QVector2D>
#include <QTimer>
#include <Eigen>

class RenderWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core {
    Q_OBJECT

public:
    explicit RenderWidget(QWidget *parent = nullptr);
    ~RenderWidget() override;

    // 渲染向量和它们的和：v1, v2 均为齐次坐标 (x, y, 0, 0)
    void showVectorSum(const QPointF &v1, const QPointF &v2);
    // 渲染矩阵分解过程 (极分解或 SVD)，m 为完整仿射矩阵
    void showMatrixTransform(const QVector4D &m);
    void showLU(const Eigen::Matrix2f &L, const Eigen::Matrix2f &U);
    void showQR(const Eigen::Matrix2f &Q, const Eigen::Matrix2f &R);
    void showEigen(const Eigen::Vector2f &values, const Eigen::Matrix2f &vectors);
    void showSolution(const QVector2D &sol);
    void clearSolution();
    void resetView();
    void clearTransform();

protected:
    // 初始化 OpenGL 上下文，仅调用一次
    void initializeGL() override;
    // 窗口大小改变时更新投影矩阵
    void resizeGL(int w, int h) override;
    // 每帧渲染逻辑入口
    void paintGL() override;
    // 鼠标按下记录，用于实现拖拽平移
    void mousePressEvent(QMouseEvent *event) override;
    // 释放鼠标
    void mouseReleaseEvent(QMouseEvent *event) override;
    // 鼠标拖动调整视图偏移
    void mouseMoveEvent(QMouseEvent *event) override;
    // 鼠标滚轮调整缩放
    void wheelEvent(QWheelEvent *event) override;
     // 键盘事件可用于重置视图或其他交互
    void keyPressEvent(QKeyEvent *event) override;

private:
    // GL 对象
    QOpenGLShaderProgram    shaderProgram_;
    QOpenGLVertexArrayObject axisVao_;
    QOpenGLBuffer           axisVbo_;

    QOpenGLVertexArrayObject tickVao_;
    QOpenGLBuffer           tickVbo_;
    int                     tickCount_ = 0;

    QOpenGLVertexArrayObject animVao_;
    QOpenGLBuffer           animVbo_;

    // State
    QPoint                  lastPos_;
    bool                    dragging_    = false;
    float                   panX_        = 0.0f;
    float                   panY_        = 0.0f;
    float                   scaleFactor_ = 1.0f;
    float                   aspect_      = 1.0f;

    QMatrix4x4              projection_, view_, model_;

    // Data
    QPointF                 vector1_, vector2_;
    bool                    displaySum_    = false;
    QVector4D               matrix_;
    bool                    displayMatrix_ = false;
    bool                    displayLU_     = false;
    bool                    displayQR_     = false;
    bool                    displayEigen_  = false;
    bool                    displaySolution_ = false;
    Eigen::Matrix2f         luL_, luU_, qrQ_, qrR_, eigVecs_;
    Eigen::Vector2f         eigVals_;
    QVector2D               solution_;

    // Animation动画区的定时器
    float                   growthFactor_ = 1.0f;
    QTimer*                 growthTimer_ = nullptr;

    // Helpers
    void initShaders();
    void buildAxisGeometry();
    void buildTickGeometry();
    void updateMatrices();
    void adjustScale(float delta);

    // Draw绘图区绘制向量
    // 绘制坐标轴及箭头
    void drawAxes();
    void drawArrow(const GLfloat arrow[6]);
    void drawAxisArrows();
    // 绘制各种变换
    void drawSum();
    void drawMatrix();
    void drawLU();
    void drawQR();
    void drawEigen();
    void drawSolution();
    void drawAnimatedLine(const QVector2D& to, const QVector3D& color);
};
